package OS

import (
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/NULL"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Slice"
	"os/exec"
	"strconv"
	"strings"
)

type sysInfo struct {
}

func (e *sysInfo) ReadDiskInfo() map[string]interface{} {
	if !Type.IsLinux() {
		return make(map[string]interface{})
	}

	cmd := exec.Command("sh", "-c", "df -h")
	lines, err := Shell.Exec(cmd)
	if err != nil {
		return nil
	}

	return e.getDiskInfo(lines)
}

func (e *sysInfo) getDiskInfo(shellLineList []string) map[string]interface{} {
	// 删除第一行信息
	if len(shellLineList) != 0 {
		Slice.Remove(&shellLineList, 0)
	}

	maxSize := 0.0
	maxMap := NULL.Type(make(map[string]interface{}))
	for _, shellLine := range shellLineList {
		items := strings.Fields(shellLine)
		if len(items) < 6 {
			continue
		}

		// df -h返回的格式
		data := make(map[string]interface{})
		data["filesystem"] = items[0]
		data["sizeTxt"] = items[1]
		data["size"] = makeNumber(items[1])
		data["used"] = makeNumber(items[2])
		data["avail"] = makeNumber(items[3])
		data["usePercentage"] = makeNumber(items[4])
		data["mounted"] = items[5]

		// 找出最大的磁盘
		thisSize := data["size"].(float64)
		if thisSize > maxSize {
			maxSize = thisSize
			maxMap = data
		}
	}

	return maxMap
}

func (e *sysInfo) ReadMemInfo() map[string]interface{} {
	if !Type.IsLinux() {
		return make(map[string]interface{})
	}

	cmd := exec.Command("sh", "-c", "free -h")
	lines, err := Shell.Exec(cmd)
	if err != nil {
		return make(map[string]interface{})
	}

	return e.getMemInfo(lines)
}

func (e *sysInfo) getMemInfo(shellLineList []string) map[string]interface{} {
	data := make(map[string]interface{})

	if len(shellLineList) < 2 {
		return data
	}

	menItems := strings.Fields(shellLineList[1])

	data["ramTotalTxt"] = menItems[1]
	data["ramTotal"] = makeNumber(menItems[1])
	data["ramUsed"] = makeNumber(menItems[2])
	data["ramFree"] = makeNumber(menItems[3])
	data["ramShared"] = makeNumber(menItems[4])
	data["ramBuffCache"] = makeNumber(menItems[5])
	data["ramAvailable"] = makeNumber(menItems[6])

	swapItems := strings.Fields(shellLineList[2])

	data["swapTotalTxt"] = swapItems[1]
	data["swapTotal"] = makeNumber(swapItems[1])
	data["swapUsed"] = makeNumber(swapItems[2])
	data["swapFree"] = makeNumber(swapItems[3])

	return data
}

func (e *sysInfo) ReadCpuInfo() map[string]interface{} {
	if !Type.IsLinux() {
		return make(map[string]interface{})
	}

	cmd := exec.Command("sh", "-c", "top -b -n 1 | grep %Cpu")
	lines, err := Shell.Exec(cmd)
	if err != nil {
		return make(map[string]interface{})
	}

	return e.getCpuInfo(lines)
}

func (e *sysInfo) getCpuInfo(shellLineList []string) map[string]interface{} {
	data := make(map[string]interface{})

	if len(shellLineList) == 0 {
		return data
	}

	items := strings.Fields(shellLineList[0])
	if len(items) < 17 {
		return data
	}

	// top -b -n 1 | grep %Cpu返回的格式
	data["us"] = makeNumber(items[1])
	data["sy"] = makeNumber(items[3])
	data["ni"] = makeNumber(items[5])
	data["id"] = makeNumber(items[7])
	data["wa"] = makeNumber(items[9])
	data["hi"] = makeNumber(items[11])
	data["si"] = makeNumber(items[13])
	data["st"] = makeNumber(items[15])

	return data
}

func makeNumber(size string) float64 {
	if size == "" {
		return 0.0
	}

	data := strings.ToUpper(size)
	if strings.HasSuffix(data, "%") {
		data = size[0 : len(data)-1]
		value, err := strconv.ParseFloat(data, 64)
		if err != nil {
			return 0
		}

		return value
	}
	if strings.HasSuffix(data, "B") {
		data = size[0 : len(data)-1]
		value, err := strconv.ParseFloat(data, 64)
		if err != nil {
			return 0
		}

		return value
	}
	if strings.HasSuffix(data, "BI") {
		data = size[0 : len(data)-2]
		value, err := strconv.ParseFloat(data, 64)
		if err != nil {
			return 0
		}

		return value
	}
	if strings.HasSuffix(data, "K") {
		data = size[0 : len(data)-1]
		value, err := strconv.ParseFloat(data, 64)
		if err != nil {
			return 0
		}

		return value * 1024
	}
	if strings.HasSuffix(data, "KI") {
		data = size[0 : len(data)-2]
		value, err := strconv.ParseFloat(data, 64)
		if err != nil {
			return 0
		}

		return value * 1024
	}
	if strings.HasSuffix(data, "M") {
		data = size[0 : len(data)-1]
		value, err := strconv.ParseFloat(data, 64)
		if err != nil {
			return 0
		}

		return value * 1024 * 1024
	}
	if strings.HasSuffix(data, "MI") {
		data = size[0 : len(data)-2]
		value, err := strconv.ParseFloat(data, 64)
		if err != nil {
			return 0
		}

		return value * 1024 * 1024
	}
	if strings.HasSuffix(data, "G") {
		data = size[0 : len(data)-1]
		value, err := strconv.ParseFloat(data, 64)
		if err != nil {
			return 0
		}

		return value * 1024 * 1024 * 1024
	}
	if strings.HasSuffix(data, "GI") {
		data = size[0 : len(data)-2]
		value, err := strconv.ParseFloat(data, 64)
		if err != nil {
			return 0
		}

		return value * 1024 * 1024 * 1024
	}

	value, err := strconv.ParseFloat(data, 64)
	if err != nil {
		return 0
	}

	return value
}
